﻿using System;
using System.Text.RegularExpressions;
using System.Xml;

namespace QDT.Payment.AllInPay.Api
{
    /// <summary>
    /// 请求报文基类
    /// </summary>
    public class Request : CustomPackage
    {
        private string m_strReqSn;
        /// <summary>
        /// 生成请求报文基本结构
        /// </summary>

        private Request()
            : base()
        {
            m_package = new XmlDocument();
            m_package.AppendChild(m_package.CreateXmlDeclaration("1.0", InternalConstants.Encode, null));
            XmlElement rootEl = m_package.CreateElement(InternalConstants.RootNode);
            m_elInfo = m_package.CreateElement("INFO");
            rootEl.AppendChild(m_elInfo);
            m_elBody = m_package.CreateElement("BODY");
            rootEl.AppendChild(m_elBody);
            m_package.AppendChild(rootEl);
        }
        private Request(string trx,string Note)
            : base()
        {
            m_package = new XmlDocument();
            m_package.AppendChild(m_package.CreateXmlDeclaration("1.0", InternalConstants.Encode, null));
            XmlElement rootEl = m_package.CreateElement(InternalConstants.RootNode);
            m_elInfo = m_package.CreateElement("INFO");
            rootEl.AppendChild(m_elInfo);
            m_elBody = m_package.CreateElement(Note);
            rootEl.AppendChild(m_elBody);
            m_package.AppendChild(rootEl);
        }
        private Request(string bodyNodeName)
            : base()
        {
            m_package = new XmlDocument();
            m_package.AppendChild(m_package.CreateXmlDeclaration("1.0", InternalConstants.Encode, null));
            XmlElement rootEl = m_package.CreateElement(InternalConstants.RootNode);
            m_elInfo = m_package.CreateElement("INFO");
            rootEl.AppendChild(m_elInfo);
            m_elBody = m_package.CreateElement(bodyNodeName);
            rootEl.AppendChild(m_elBody);
            m_package.AppendChild(rootEl);
        }

        /// <summary>
        /// 生成请求报文并填充INFO区基本信息
        /// </summary>
        /// <param name="trxCode">交易代码</param>
        /// <param name="version">版本号</param>
        /// <param name="dataType">数据类型 目前仅支持2:xml</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">用户密码</param>
        /// <param name="reqSn">交易流水号</param>
        protected Request(string trxCode,string version,int dataType,string userName,string password,string reqSn,string Note)
            : this("100011",Note)
        {
            m_elInfo.AppendChild(CreateValueElement("TRX_CODE", trxCode));
            m_elInfo.AppendChild(CreateValueElement("VERSION", version));
            m_elInfo.AppendChild(CreateValueElement("DATA_TYPE", dataType.ToString()));
            if (userName == null || !Regex.IsMatch(userName, "^.{1,20}$"))
                throw new FormatException("用户名格式错误，应为C(1,20)");
            m_elInfo.AppendChild(CreateValueElement("USER_NAME", userName));
            m_elInfo.AppendChild(CreateValueElement("USER_PASS", password));
            if (userName == null || !Regex.IsMatch(reqSn, "^.{1,30}$"))
                throw new FormatException("交易流水号错误，应为C(40)");
            m_elInfo.AppendChild(CreateValueElement("REQ_SN", reqSn));
            m_elInfo.AppendChild(m_package.CreateElement("SIGNED_MSG"));

            m_strReqSn = reqSn;
        }

        /// <summary>
        /// 生成请求报文并填充INFO区基本信息
        /// </summary>
        /// <param name="trxCode">交易代码</param>
        /// <param name="version">版本号</param>
        /// <param name="dataType">数据类型 目前仅支持2:xml</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">用户密码</param>
        /// <param name="reqSn">交易流水号</param>
        protected Request(string bodyNodeName, string trxCode, string version, int dataType, string userName, string password, string reqSn)
            : this(bodyNodeName)
        {
            m_elInfo.AppendChild(CreateValueElement("TRX_CODE", trxCode));
            m_elInfo.AppendChild(CreateValueElement("VERSION", version));
            m_elInfo.AppendChild(CreateValueElement("DATA_TYPE", dataType.ToString()));
            if (userName == null || !Regex.IsMatch(userName, "^.{1,20}$"))
                throw new FormatException("用户名格式错误，应为C(1,20)");
            m_elInfo.AppendChild(CreateValueElement("USER_NAME", userName));
            m_elInfo.AppendChild(CreateValueElement("USER_PASS", password));
            if (userName == null || !Regex.IsMatch(reqSn, "^.{1,40}$"))
                throw new FormatException("交易流水号错误，应为C(40)");
            m_elInfo.AppendChild(CreateValueElement("REQ_SN", reqSn));
            m_elInfo.AppendChild(m_package.CreateElement("SIGNED_MSG"));

            m_strReqSn = reqSn;
        }

        /// <summary>
        /// 获取本次交易流水号
        /// </summary>
        public string ReqSn
        {
            get { return m_strReqSn; }
        }

        protected XmlElement CreateValueElement(string name, string value)
        {
            return CreateValueElement(m_package, name, value);
        }

        internal virtual void BeforeSend()
        {
        }
    }
}
